﻿using System;
using RayDen.Library.Core.Primitives;

namespace RayDen.Library.Data
{

    //TODO ADD Filename as a part of map name

    public class CubeMap : EnvironmentSamplerBase,  IEnvironmentMapSampler
    {
        private RgbSpectrumTexture Top, Left, Right, Bottom, Forward, Backward;
        public string Name
        {
            get { return "Cube_Envmap"; }
        }
        public string FileName
        {
            get { return Top.filePath; }
        }

        public CubeMap(string up, string down, string left, string right, string fwd, string back)
        {
            Top = LoadTexture(up);
            Left = LoadTexture(left);
            Right = LoadTexture(right);
            Bottom = LoadTexture(down);
            Forward = LoadTexture(fwd);
            Backward = LoadTexture(back);
        }

        public void Sample(ref Vector dir, out RgbSpectrumInfo outputColor)
        {
            outputColor = new RgbSpectrumInfo(0f);

            if ((Math.Abs(dir.x) >= Math.Abs(dir.y))
                && (Math.Abs(dir.x) >= Math.Abs(dir.z)))
            {
                if (dir.x > 0.0f)
                {
                    outputColor = Right.Sample(
                        1.0f - (dir.z / dir.x + 1.0f) * 0.5f, (dir.y / dir.x + 1.0f) * 0.5f);
                }
                else if (dir.x < 0.0f)
                {

                    outputColor = Left.Sample(
                        1.0f - (dir.z / dir.x + 1.0f) * 0.5f,
                        1.0f - (dir.y / dir.x + 1.0f) * 0.5f);

                }
            }
            else if ((Math.Abs(dir.y) >= Math.Abs(dir.x)) && (Math.Abs(dir.y) >= Math.Abs(dir.z)))
            {
                if (dir.y > 0.0f)
                {
                    outputColor = Top.Sample((dir.x / dir.y + 1.0f) * 0.5f,
                                              1.0f - (dir.z / dir.y + 1.0f) * 0.5f);
                }
                else if (dir.y < 0.0f)
                {
                    outputColor = Bottom.Sample(
                                              1.0f - (dir.x / dir.y + 1.0f) * 0.5f,
                                              (dir.z / dir.y + 1.0f) * 0.5f);
                }
            }
            else if ((Math.Abs(dir.z) >= Math.Abs(dir.x))
                     && (Math.Abs(dir.z) >= Math.Abs(dir.y)))
            {
                if (dir.z > 0.0f)
                {
                    outputColor = Forward.Sample((dir.x / dir.z + 1.0f) * 0.5f, (dir.y / dir.z + 1.0f) * 0.5f);
                }
                else if (dir.z < 0.0f)
                {
                    outputColor = Backward.Sample((dir.x / dir.z + 1.0f) * 0.5f,
                                              1.0f - (dir.y / dir.z + 1) * 0.5f);
                }
            }
        }


        public void SampleBackground(ref Vector dir, out RgbSpectrumInfo outputColor)
        {
            Sample(ref dir, out outputColor);
        }
    }
}